﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Windows.Media;
using Styx;
using Styx.Helpers;
using Styx.Common;
using Styx.CommonBot.POI;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;


namespace ElementalMyDear
{
    public partial class Classname : CombatRoutine
    {
        public string LastSpell = "";
        /*public string LavaSurge = "Lava Surge"; //proc
        public string ElementalFocus = "Elemental Focus"; //proc
        public string LavaBurst = "Lava Burst";
        public string ElementalBlast = "Elemental Blast";
        public string EarthShock = "Earth Shock"; //with 6-7 charges lightning shield
        public string WindShear = "Wind Shear";
        public string UnleashElements = "Unleash Elements";
        public string ShamanisticRage = "Shamanistic Rage";

        //Fire Totems
        public string SearingTotem = "Searing Totem";
        public string MagmaTotem = "Magma Totem";
        public string FireElementalTotem = "Fire Elemental Totem";

        //Earth Totems
        public string EarthgrabTotem = "Earthgrab Totem";
        public string TremorTotem = "Tremor Totem";
        public string EarthElementalTotem = "Earth Elemental Totem";
        public string StoneBulwarkTotem = "Stone Bulwark Totem";


        //WaterTotems
        public string HealingStreamTotem = "Healing Stream Totem";
        public string HealingTideTotem = "Healing Tide Totem";


        //AirTotems
        public string GroundingTotem = "Grounding Totem"; //25 sec cd
        public string StormlashTotem = "Stormlash Totem";
        public string WindwalkTotem = "Windwalk Totem";


        public string LightningBolt = "Lightning Bolt";
        public string RollingThunder = "Rolling Thunder";
        public string FlametongueWeapon = "Flametongue Weapon";
        public string LightningShield = "Lightning Shield";
        public string FlameShock = "Flame Shock";

        public string Earthquake = "Earthquake";
        public string Thunderstorm = "Thunderstorm";
        public string ChainLightning = "Chain Lightning";

        */

        public bool UseSpells
        {
            get
            {
                if (Me.CurrentTarget == null
                    && Me.Mounted
                    || (Me.IsGhost
                    || Me.IsDead)
                    || (Me.HasAura("Drink")
                    || Me.HasAura("Food")
                    || Me.HasAura("First Aid")))
                {
                    return false;
                }
                return true;
            }
        }
        public void CastSpell(string spell, int logColor)
        {
            if(SpellManager.CanCast(spell))
            { 
                SpellManager.Cast(spell, Me.CurrentTarget);
                LogMsg(spell, logColor);
                LastSpell = spell;
            }
        }
        public void CastBuff(string spell, int logColor)
        {
            if (SpellManager.CanCast(spell) )
            { 
                SpellManager.Cast(spell, StyxWoW.Me);
                LogMsg(spell, logColor);
                LastSpell = spell;
                
            }
        }
        #region Use Skill
        public bool UseSkill(string spell)
        {
            if (Me.CurrentTarget != null
                && Me.CurrentTarget.IsAlive
                && SpellManager.HasSpell(spell))
            {
                return true;
            }
            return false;
        }
        #endregion Use Skill

        public bool IsEnemy(WoWUnit target)
        {
            if (target == null)
            {
                return false;
            }

            if (!target.IsFriendly || target.Name.Contains("Dummy")
                && StyxWoW.Me.Location.Distance(target.Location) <= 40
                && target.Attackable
                && target.InLineOfSpellSight)
            {
                return true;
            }
            return false;
        }

        public static void EnsureTarget()
        { 
            WoWObject ctx = GatherTarget();
            if (ctx != null)
            {
                Logging.Write("Switching to " + ctx + "!");
                ((WoWUnit)ctx).Target();
            }
        }
        private static WoWObject GatherTarget()
        {
            if (StyxWoW.Me.CurrentTarget == null || StyxWoW.Me.CurrentTarget.IsDead)
                return null;
            if (StyxWoW.Me.CurrentTarget == null || StyxWoW.Me.CurrentTarget.IsPet)
                return null;
            if (StyxWoW.Me.CurrentTarget != null && (StyxWoW.Me.CurrentTarget.Combat || StyxWoW.Me.CurrentTarget.Aggro))
                return null;
            if (StyxWoW.Me.CurrentTarget != null && StyxWoW.Me.Location.Distance(Me.CurrentTarget.Location) > 40)
                return null;
            if (BotPoi.Current.Type == PoiType.Kill)
            {
                var obj = BotPoi.Current.AsObject;

                if (obj != null)
                {
                    if (StyxWoW.Me.CurrentTarget != obj)
                        return obj;
                }
            }
            var firstUnit = Targeting.Instance.FirstUnit;

            if (firstUnit != null)
            {
                if (StyxWoW.Me.CurrentTarget != firstUnit)
                    return firstUnit;
            }
            return null;
        }
 
        
        #region Kind of target
        public bool IsBoss
        {
            get
            {
                if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.WorldBoss)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && target.IsBoss(Me.CurrentTarget))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.MaxHealth >= (60 * 1000000))
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.CreatureRank == WoWUnitClassificationType.Elite
                    && Me.CurrentTarget.MaxHealth >= (Me.MaxHealth * ShammySettings.myPrefs.elitehealth)
                    && !Me.GroupInfo.IsInParty
                    && !Me.IsInInstance
                    && !Me.GroupInfo.IsInRaid)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.Name.Contains("Training Dummy")
                    && !Me.IsInInstance)
                {
                    return true;
                }
                else if (Me.CurrentTarget != null
                    && Me.CurrentTarget.IsPlayer
                    && !Me.CurrentTarget.IsFriendly)
                {
                    return true;
                }
                return false;
            }
        }

        #endregion Kind of Target

        #region AddCounting
        private int addCount
        {
            get
            {
                int count = 0;
                foreach (WoWUnit u in ObjectManager.GetObjectsOfType<WoWUnit>(true, true))
                {
                    if (u.CanSelect
                        && !u.IsPlayer
                        && u.IsAlive
                        && u.Guid != Me.Guid
                        && !u.IsFriendly
                        && u.IsHostile
                        && u.Attackable
                        && !u.IsTotem
                        && !u.IsCritter
                        && !u.IsNonCombatPet
                        && (u.Location.Distance(Me.CurrentTarget.Location) <= 10 || u.Location.Distance2D(Me.CurrentTarget.Location) <= 10))
                    {
                        count++;
                    }
                }
                return count;
            }
        }
        #endregion AddCounting

        #region logs
        public void LogMsg(string msg, int kleurtje)
        {
            Color kleur = Colors.Yellow;
            switch (kleurtje)
            {
                case 0:
                    kleur = Colors.Orange;
                    break;
                case 1:
                    kleur = Colors.PaleGreen;
                    break;
                case 2:
                    kleur = Colors.BlanchedAlmond;
                    break;
                case 3:
                    kleur = Colors.Yellow;
                    break;
                case 4:
                    kleur = Colors.Red;
                    break;
                case 5:
                    kleur = Colors.Crimson;
                    break;
                case 6:
                    kleur = Colors.LightBlue;
                    break;
                case 7:
                    kleur = Colors.Cyan;
                    break;
                case 8:
                    kleur = Colors.DarkSeaGreen; // TotH
                    break;
                case 9:
                    kleur = Colors.ForestGreen; //Lock and load
                    break;
                case 10:
                    kleur = Colors.DeepSkyBlue; //focusdump
                    break;
            }
            Logging.Write(kleur, msg);
            LastSpell = msg;
        }
        #endregion logs

         
        #region Trinkets
        public void UseTrinket1()
        { 
                var firstTrinket = StyxWoW.Me.Inventory.Equipped.Trinket1;

                if (ShammySettings.myPrefs.Mtrinket1 != 0)
                {
                    if (ShammySettings.myPrefs.Mtrinket1 == 2
                        && IsBoss)
                    {

                        if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                        {
                            firstTrinket.Use();
                            LogMsg("Using 1st trinket", 2);
                        }
                    }
                    else if (ShammySettings.myPrefs.Mtrinket1 == 1)
                    {
                        if (firstTrinket != null && CanUseEquippedItem(firstTrinket))
                        {
                            firstTrinket.Use();
                            LogMsg("Using 1st trinket", 2);
                        }
                    }
                }
        }
        public void UseTrinket2()
        {
                var secondTrinket = StyxWoW.Me.Inventory.Equipped.Trinket2;

                if (ShammySettings.myPrefs.Mtrinket2 == 2
                    && IsBoss)
                {
                    if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                    {
                        secondTrinket.Use();
                        LogMsg("Using 2nd trinket", 2);
                    }
                }
                else if (ShammySettings.myPrefs.Mtrinket2 == 1)
                {
                    if (secondTrinket != null && CanUseEquippedItem(secondTrinket))
                    {
                        secondTrinket.Use();
                        LogMsg("Using 2nd trinket", 2);
                    }
                }
        }
        public void UseEngibelt()
        {
            if (Me.CurrentTarget != null
                && ShammySettings.myPrefs.Mengibelt != 0)
            {
                var engiBelt = StyxWoW.Me.Inventory.Equipped.Waist;

                if (ShammySettings.myPrefs.Mengibelt == 2
                    && IsBoss)
                {
                    if (engiBelt != null && CanUseEquippedItem(engiBelt))
                    {
                        engiBelt.Use();
                        LogMsg("Using Engineer Belt", 2);
                    }
                }
                else if (ShammySettings.myPrefs.Mengibelt == 1)
                {
                    if (engiBelt != null && CanUseEquippedItem(engiBelt))
                    {
                        engiBelt.Use();
                        LogMsg("Using Engineer Belt", 2);
                    }
                }
            }
        }
        public void UseEngiGloves()
        {
            if (Me.CurrentTarget != null
                && ShammySettings.myPrefs.Mengivloves != 0)
            {
                var engiGloves = StyxWoW.Me.Inventory.Equipped.Hands;

                if (ShammySettings.myPrefs.Mengivloves == 2
                    && IsBoss)
                {
                    if (engiGloves != null && CanUseEquippedItem(engiGloves))
                    {
                        engiGloves.Use();
                        LogMsg("Using Engineer Gloves", 2);
                    }
                }
                else if (ShammySettings.myPrefs.Mengivloves == 1)
                {
                    if (engiGloves != null && CanUseEquippedItem(engiGloves))
                    {
                        engiGloves.Use();
                        LogMsg("Using Engineer Gloves", 2);
                    }
                }
            }
        }
        private static bool CanUseEquippedItem(WoWItem item)
        {
            // Check for engineering tinkers!
            string itemSpell = Lua.GetReturnVal<string>("return GetItemSpell(" + item.Entry + ")", 0);
            if (string.IsNullOrEmpty(itemSpell))
                return false;


            return item.Usable && item.Cooldown <= 0;
        }
        #endregion Trinkets

        #region usetrinkets
        private void UseMyTrinkets()
        {
            if (ShammySettings.myPrefs.Mtrinket1 != 0
                && Me.CurrentTarget != null)
            {
                UseTrinket1();
            }
            if (ShammySettings.myPrefs.Mtrinket2 != 0
                && Me.CurrentTarget != null)
            {
                UseTrinket2();
            }
            if (ShammySettings.myPrefs.Mengivloves != 0
                && Me.CurrentTarget != null)
            {
                UseEngiGloves();
            }
        }
        #endregion usetrinkets

        #region Movement
        public void MoveInRange(float dist)
        {
            if (Me.CurrentTarget != null)
            {
                float range = dist;
                while (Me.CurrentTarget != null
                    && StyxWoW.Me.Location.Distance(StyxWoW.Me.CurrentTarget.Location) > range)
                {
                    Navigator.MoveTo(StyxWoW.Me.CurrentTarget.Location);
                };
                Navigator.PlayerMover.MoveStop();
            }

        }
        public void MoveBack(WoWMovement.MovementDirection direction)
        {
            MoveBackTimer.Start();

            while (MoveBackTimer.Elapsed.Seconds != 1)
            {
                WoWMovement.Move(direction);
            }

            Navigator.PlayerMover.MoveStop();
            MoveBackTimer.Reset();
        }
        public void MoveInLignOfSight()
        {
            while (!Me.CurrentTarget.InLineOfSight)
            {
                Navigator.MoveTo(StyxWoW.Me.CurrentTarget.Location);
            }
            Navigator.PlayerMover.MoveStop();
        }
        #endregion Movement

        #region totemreset
        public void ResetTotems()
        { 
            //fire totems
            SearingTimer.Reset();
            MagmaTimer.Reset();
            FireElementalTimer.Reset();
                
        }
        #endregion totemreset

        #region reset timers
        public void ResetTimers()
        {
            //firetotems
            SearingTimer.Reset();
            MagmaTimer.Reset();
            FireElementalTimer.Reset();
        }
        #endregion reset timers

        public bool UseEarthquake
        {
            get
            {
                if (ShammySettings.myPrefs.earthquake == 0)
                {
                    return false;
                }
                if (ShammySettings.myPrefs.earthquake == 2)
                {
                    return true;
                }
                if (ShammySettings.myPrefs.earthquake == 1
                    && Me.GroupInfo.IsInParty
                    || Me.GroupInfo.IsInRaid
                    || Me.IsInInstance)
                {
                    return true;
                }
                return false;
            }
        }
        public bool UseAscendance
        {
            get
            {
                if (ShammySettings.myPrefs.ascendance == 2
                    && targetExistence(Me.CurrentTarget) >= 25)
                {
                    return true;
                }
                if (ShammySettings.myPrefs.ascendance == 1
                    && targetExistence(Me.CurrentTarget) >= 10
                    && IsBoss)
                {
                    return true;
                }
                return false;
            }
        }
        public bool UseBloodFury
        {
            get
            {
                if (ShammySettings.myPrefs.bloodfury == 1
                    && targetExistence(Me.CurrentTarget) >= 25)
                {
                    return true;
                }
                if (ShammySettings.myPrefs.bloodfury == 2
                    && targetExistence(Me.CurrentTarget) >= 10
                    && IsBoss)
                {
                    return true;
                }
                return false;
            }
        }
        public bool UseBerserking
        {
            get
            {
                if (ShammySettings.myPrefs.berserking == 1
                    && targetExistence(Me.CurrentTarget) >= 25)
                {
                    return true;
                }
                if (ShammySettings.myPrefs.berserking == 2
                    && targetExistence(Me.CurrentTarget) >= 10
                    && IsBoss)
                {
                    return true;
                }
                return false;
            }
        }
        #region pause

        public bool Paused = false;

        public override void ShutDown()
        {
            Lua.Events.DetachEvent("MODIFIER_STATE_CHANGED", HandleModifierStateChanged);
        }

        private void HandleModifierStateChanged(object sender, LuaEventArgs args)
        {
            if (ShammySettings.myPrefs.PauseKeys == ShammySettings.Keypress.None)
            {
                return;
            }

            if (Convert.ToInt32(args.Args[1]) == 1)
            {
                if (args.Args[0].ToString() == ShammySettings.myPrefs.PauseKeys.ToString())
                {
                    Paused = !Paused;
                    if (Paused)
                    {
                        Logging.Write("Shammy PAUSED, press {0} in WOW to continue",
                                     ShammySettings.myPrefs.PauseKeys.ToString());
                        if (ShammySettings.myPrefs.PrintMsg)
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"Shammy PAUSED\", ChatTypeInfo[\"RAID_WARNING\"]);");
                    }
                    else
                    {
                        Logging.Write("Superbad Running....");
                        if (ShammySettings.myPrefs.PrintMsg)
                            Lua.DoString(
                                "RaidNotice_AddMessage(RaidWarningFrame, \"Shammy Resumed\", ChatTypeInfo[\"RAID_WARNING\"]);");
                    }
                }
            }
        }
        #endregion pause

        public bool NeedShamanisticRage
        {
            get
            {
                if (ShammySettings.myPrefs.shamanisticrage == 1
                    && LastSpellID != ShamanisticRage)
                {
                    return true;
                }
                if (ShammySettings.myPrefs.shamanisticrage == 2
                    && IsBoss
                     && LastSpellID != ShamanisticRage)
                {
                    return true;
                }
                return false;
            }
        }
         
        public bool UseSearingTotem
        {
            get
            {
                if (!SearingTimer.IsRunning
                    && !MagmaTimer.IsRunning
                    && !FireElementalTimer.IsRunning
                    && ShammySettings.myPrefs.searingtotem == 1)
                {
                    SearingTimer.Reset();
                    return true;
                }
                if (SearingTimer.Elapsed.Seconds > 58
                    && ShammySettings.myPrefs.searingtotem == 1)
                {
                    SearingTimer.Reset();
                    return true;
                }
                return false;
            }
        }
        public bool UseMagmaTotem
        {
            get
            {
                if (!FireElementalTimer.IsRunning
                    && !MagmaTimer.IsRunning
                    && addCount >= ShammySettings.myPrefs.startaoe
                    && ShammySettings.myPrefs.magmatotem == 1
                    && nearbyTargets(Me.CurrentTarget.Location, 12).Count() >= ShammySettings.myPrefs.startaoe)
                {
                    MagmaTimer.Reset();
                    if (SearingTimer.IsRunning) { SearingTimer.Reset(); }
                    return true;
                }
                if (MagmaTimer.Elapsed.Seconds > 58
                    && addCount >= ShammySettings.myPrefs.startaoe
                    && ShammySettings.myPrefs.magmatotem == 1
                    && nearbyTargets(Me.CurrentTarget.Location, 12).Count() >= ShammySettings.myPrefs.startaoe)
                {
                    MagmaTimer.Reset();
                    if (SearingTimer.IsRunning) { SearingTimer.Reset(); }
                    return true;
                }
                return false;
            }
        }









    }
}
